﻿
Imports osi.root.constants
Imports osi.root.lock
Imports osi.root.formation
Imports osi.root.procedure
Imports osi.root.connector
Imports osi.root.utils

Partial Public Class device_pool(Of T)
    Inherits device_pool

    ' ATTENTION, two device_pools may export same interface T, which is also by-design
    ' validator / closer / device_id cannot use binder
    Private Shared ReadOnly default_identity As String
    Private ReadOnly ctor As Func(Of pointer(Of T), event_comb)
    Private ReadOnly validator As Func(Of T, Boolean)
    Private ReadOnly closer As Action(Of T)
    Private ReadOnly device_id As Func(Of T, String)

    Shared Sub New()
        default_identity = GetType(T).Name()
    End Sub

    Protected Sub New(ByVal max_count As UInt32,
                      ByVal identity As String,
                      ByVal ctor As Func(Of pointer(Of T), event_comb),
                      ByVal validator As Func(Of T, Boolean),
                      ByVal closer As Action(Of T),
                      ByVal device_id As Func(Of T, String))
        MyBase.New(max_count, strcat(If(String.IsNullOrEmpty(identity), default_identity, identity), "_DEVICE_POOL"))
        Me.ctor = ctor
        Me.validator = validator
        Me.closer = closer
        Me.device_id = device_id
    End Sub

    Protected Sub New(ByVal max_count As UInt32,
                      ByVal ctor As Func(Of pointer(Of T), event_comb),
                      ByVal validator As Func(Of T, Boolean),
                      ByVal closer As Action(Of T),
                      ByVal device_id As Func(Of T, String))
        Me.New(max_count, Nothing, ctor, validator, closer, device_id)
    End Sub

    Protected Sub New(ByVal identity As String,
                      ByVal ctor As Func(Of pointer(Of T), event_comb),
                      ByVal validator As Func(Of T, Boolean),
                      ByVal closer As Action(Of T),
                      ByVal device_id As Func(Of T, String))
        Me.New(uint32_0, identity, ctor, validator, closer, device_id)
    End Sub

    Protected Sub New(ByVal ctor As Func(Of pointer(Of T), event_comb),
                      ByVal validator As Func(Of T, Boolean),
                      ByVal closer As Action(Of T),
                      ByVal device_id As Func(Of T, String))
        Me.New(uint32_0, default_identity, ctor, validator, closer, device_id)
    End Sub

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
        GC.KeepAlive(ctor)
        GC.KeepAlive(closer)
        GC.KeepAlive(validator)
    End Sub

    Protected Shared Sub async_closer_to_sync(ByVal closer As Func(Of event_comb),
                                              ByVal device_id As String,
                                              ByVal pool_id As String)
        assert(Not closer Is Nothing)
        If Not async_sync(closer()) Then
            raise_error(error_type.warning,
                        "device ",
                        device_id,
                        " in pool ",
                        pool_id,
                        " has not been correctly closed")
        End If
    End Sub

    Protected Shared Sub async_closer_to_sync(ByVal d As T,
                                              ByVal closer As Func(Of T, event_comb),
                                              ByVal device_id As Func(Of T, String),
                                              ByVal pool_id As String)
        assert(Not closer Is Nothing)
        assert(Not device_id Is Nothing)
        async_closer_to_sync(Function() As event_comb
                                 Return closer(d)
                             End Function,
                             device_id(d),
                             pool_id)
    End Sub

    Protected Shared Function async_closer_to_sync(ByVal closer As Func(Of T, event_comb),
                                                   ByVal device_id As Func(Of T, String),
                                                   ByVal pool_id As String) As Action(Of T)
        If closer Is Nothing OrElse device_id Is Nothing Then
            Return Nothing
        Else
            Return Sub(x As T)
                       async_closer_to_sync(x, closer, device_id, pool_id)
                   End Sub
        End If
    End Function

    Protected Sub async_closer_to_sync(ByVal d As T, ByVal closer As Func(Of T, event_comb))
        async_closer_to_sync(d, closer, AddressOf device_identity, identity())
    End Sub

    Protected Sub async_closer_to_sync(ByVal d As T, ByVal closer As Func(Of event_comb))
        async_closer_to_sync(closer, device_identity(d), identity())
    End Sub
End Class
